package KUtilities;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Properties;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;


public final class KSwing
{
	public static JFrame gui;
	private static BufferedImage backgroundImage;
	public static JPanel disabler,background,transparent;
	public static KSpringOld mainSpring;
	public static JLayeredPane main;
	@SuppressWarnings("rawtypes")
	private final static HashMap<String,Class> plafList=new HashMap<String,Class>();
		
	private static void addLook(String lookName,String lookClass)
	{
		try{
			plafList.put(lookName,Class.forName(lookClass));
		}catch(Exception e){}
	}
	
	static
	{
		addLook("Windows","com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		addLook("Nimbus","com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
		addLook("Sea Glass","com.seaglasslookandfeel.SeaGlassLookAndFeel");
		addLook("Simple 2D","de.javasoft.plaf.synthetica.SyntheticaSimple2DLookAndFeel");		
		String[] li = {"Licensee=Alvaro Duran Tovar  ","LicenseRegistrationNumber=------", "Product=Synthetica",
                		"LicenseType=Non Commercial", "ExpireDate=--.--.----","MaxVersion=2.999.999"};
		UIManager.put("Synthetica.license.info", li);
        UIManager.put("Synthetica.license.key","7C970FF4-E59D6AF5-8376C987-6F82C092-8377BB97");
        UIDefaults defaults=UIManager.getLookAndFeelDefaults();
		defaults.put("Panel.background", new Color(0,0,0,0));
		defaults.put("RootPane.background", new Color(0,0,0,0));
        Properties laf=new Properties();
        try {
			laf.load(new FileReader("lib"+File.separator+"skins"+File.separator+"default.ini"));
			setLookAndFeel(laf.get("default").toString());
		} catch (Exception e) {
			setLookAndFeel("Nimbus");
		}
	}
	
	/**
	 * Returns the set of LookAndFeels available
	 * @return names of all LookAndFeels Names
	 */
	public static String[] getLookAndFeels()
	{
		String result[] = null;
		Object[] templist=plafList.keySet().toArray();
		result=new String[templist.length];
		for(int i=0;i<templist.length;i++)
		{
			result[i]=templist[i].toString();
		}
		return result;
	}
	
	/**
	 * Sets the Default LookAndFeel
	 */
	public static void setDefaultLookAndFeel()
	{
		Properties laf=new Properties();
		try {
			laf.load(new FileReader("lib"+File.separator+"skins"+File.separator+"default.ini"));
			setLookAndFeel(laf.get("default").toString());
		} catch (Exception e) {
			setLookAndFeel("Nimbus");
		}
	}
	
	/**
	 * Sets the LookAndFeel
	 * @param name LookAndFeel name
	 */
	public static void setLookAndFeel(String name)
	{
		try
		{
			JFrame.setDefaultLookAndFeelDecorated(true);
			UIManager.setLookAndFeel(plafList.get(name).getName());
			final Properties lafPro=new Properties();
			lafPro.setProperty("default", name);
			lafPro.store(new FileWriter("lib"+File.separator+"skins"+File.separator+"default.ini"), null);
			SwingUtilities.updateComponentTreeUI(gui);
			//gui.setVisible(true);
		}catch(Exception e){}
	}
	
	/**
	 * Add the <code>components</code> to the container
	 * @param child : components to add
	 * @param parent: parent container
	 */
	public static void addComponents(JComponent parent,JComponent... child)
	{
		for(JComponent temp:child)
		{
			try
			{
				parent.add(temp);
			}catch(NullPointerException ex)
			{
				System.out.println("Parent Component does not Exist");
			}
		}
	}
	
	/**
	 * adds action listener to all the buttons
	 * @param action listener to add
	 * @param buttons to whom action has to be added
	 */
	public static void addActionListener(ActionListener action,JButton... buttons)
	{
		for(int i=0;i<buttons.length;i++)
		{
			buttons[i].addActionListener(action);
		}
	}
	
	/**
	 * Disables the component and its children components
	 * @param parent component to disable
	 */
	public static void disable(Container parent)
	{
		if(parent.getComponentCount()>0)
		{
			for(Component temp:parent.getComponents())
			{
				disable((Container)temp);
			}
		}
		parent.setEnabled(false);
	}
		
	/**
	 * Enables the component and its children components
	 * @param parent component to enable
	 */
	public static void enable(Container parent)
	{
		if(parent.getComponentCount()>0)
		{
			for(Component temp:parent.getComponents())
			{
				enable((Container)temp);
			}
		}
		parent.setEnabled(true);
	}
	
	/**
	 * Sets the container to center of screen
	 * @param frame container to set to center of screen
	 */
	public static void setCenterToScreen(Container frame)
	{
		Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
		int x=(int) (screenSize.getWidth()/2-frame.getWidth()/2);
		int y=(int) (screenSize.getHeight()/2-frame.getHeight()/2);
		frame.setLocation(x,y);
	}
	
	/**
	 * Sets the Dialog to center of parent container
	 * @param frame container to set to center
	 * @param parent container to set Center relative to
	 */
	public static void setCenterToComponent(JDialog dialog,Container parent)
	{
		if(parent!=null)
		{	Dimension screenSize=parent.getSize();
			int x=(int) (screenSize.getWidth()/2-dialog.getWidth()/2);
			int y=(int) (screenSize.getHeight()/2-dialog.getHeight()/2);
			dialog.setLocation(x,y);
			dialog.setLocationRelativeTo(parent);
		}
	}
	
	/**
	 * Changes the font of the Look and Feel
	 * @param name Name of the font
	 */
	public static void setFont(String name)
	{
		setFont(name,0);
	}
	
	/**
	 * Changes the font of the Look and Feel
	 * @param name Name of the font
	 * @sizeIncrement increase in size of font
	 */
	public static void setFont(String name,int sizeIncrement)
	{
		UIDefaults defaults=UIManager.getLookAndFeelDefaults();
		Enumeration<Object> keysList=defaults.keys();
		while(keysList.hasMoreElements())
		{
			Object key=keysList.nextElement();
			Object value=defaults.get(key);
			if(value instanceof Font)
			{
				Font temp=(Font)value;
				Font f=new Font(name,temp.getStyle(),temp.getSize()+sizeIncrement);
				defaults.put(key, f);
			}
		}
		SwingUtilities.updateComponentTreeUI(gui);
	}
	
	/**
	 * Changes the font of the Look and Feel
	 * @param fontFile File object to the user font
	 */
	public static void setFont(File fontFile)
	{
		setFont(fontFile,0);
	}
	
	/**
	 * Changes the font of the Look and Feel
	 * @param fontFile File object to the user font
	 * @sizeIncrement increase in size of font
	 */
	public static boolean setFont(File fontFile,int sizeIncrement)
	{
		Font userFont = null;
		try {
			userFont = Font.createFont(Font.TRUETYPE_FONT, fontFile);
		} catch (Exception e) {
			try {
				userFont = Font.createFont(Font.TYPE1_FONT, fontFile);
			} catch (Exception e2) {
				System.out.println("Fail");
				return false;
			}
		}
		UIDefaults defaults=UIManager.getLookAndFeelDefaults();
		Enumeration<Object> keysList=defaults.keys();
		while(keysList.hasMoreElements())
		{
			Object key=keysList.nextElement();
			Object value=defaults.get(key);
			if(value instanceof Font)
			{
				Font temp=(Font)value;
				Font f=userFont.deriveFont(temp.getStyle(), temp.getSize2D()+sizeIncrement);
				defaults.put(key, f);
			}
		}
		SwingUtilities.updateComponentTreeUI(gui);
		return true;
	}
	
	/**
	 * Create a disabler panel of given width and height
	 * @param width width of the panel
	 * @param height height of the panel
	 * @return a panel capable of disabling others behind it
	 */
	public static JPanel createDisablerPanel(final int width,final int height)
	{
		disabler=new JPanel()
		{
			private static final long serialVersionUID = 1L;
			{
				setPreferredSize(new Dimension(width,height));
				setOpaque(false);
				addMouseListener(new MouseAdapter(){
					public void mouseEntered(MouseEvent me)
					{
						me.consume();
					}
				});
				requestFocus();
			}
			public void paintComponent(Graphics g)
			{
				if(gui.getWidth()!=getWidth()||gui.getHeight()!=getHeight()){
					setPreferredSize(new Dimension(gui.getWidth(),gui.getHeight()));
					SwingUtilities.updateComponentTreeUI(this);
				}
				Graphics2D g2=(Graphics2D)g.create();
				float fractions[]={0,0.5f,1};
				Color colors[]={new Color(0,0,0,175),new Color(0,0,0,145),new Color(0,0,0,115)};
				LinearGradientPaint paint=new LinearGradientPaint(0,0,getWidth(),getHeight(),fractions,colors);
				g2.setPaint(paint);
				g2.fillRect(0, 0, getWidth(), getHeight());
			}
		};
		return disabler;
	}
	
	

	/**
	 * Create a transparent panel of given width and height
	 * @param width width of the panel
	 * @param height height of the panel
	 * @return a panel capable of disabling others behind it
	 */
	public static JPanel createTransparentPanel(final int width,final int height)
	{
		transparent=new JPanel()
		{
			private static final long serialVersionUID = 1L;
			{
				setPreferredSize(new Dimension(width,height));
				setOpaque(false);
				addMouseListener(new MouseAdapter(){
					public void mouseEntered(MouseEvent me)
					{
						me.consume();
					}
				});
			}
			public void paintComponent(Graphics g)
			{
				if(gui.getWidth()!=getWidth()||gui.getHeight()!=getHeight()){
					setPreferredSize(new Dimension(gui.getWidth(),gui.getHeight()));
					SwingUtilities.updateComponentTreeUI(this);
				}
				Graphics2D g2=(Graphics2D)g.create();
				float fractions[]={0,0.5f,1};
				Color colors[]={new Color(0,0,0,175),new Color(0,0,0,145),new Color(0,0,0,115)};
				//Color colors[]={new Color(0,0,0,0),new Color(0,0,0,0)};
				LinearGradientPaint paint=new LinearGradientPaint(0,0,getWidth(),getHeight(),fractions,colors);
				g2.setPaint(paint);
				g2.fillRect(0, 0, getWidth(), getHeight());
			}
		};
		return transparent;
	}
	
	/**
	 * Create a panel of given width and height with give image as background
	 * @param image file locating the image
	 * @param width width of the panel
	 * @param height height of the panel
	 * @return a panel capable of disabling others behind it
	 */
	public static JPanel createBackGroundPanel(final File image,final int width,final int height)
	{
		background=new JPanel()
		{
			private static final long serialVersionUID = 1L;
			{
				setPreferredSize(new Dimension(width,height));
			}
			public void paintComponent(Graphics g)
			{
				if(gui.getWidth()!=getWidth()||gui.getHeight()!=getHeight())
					setPreferredSize(new Dimension(gui.getWidth(),gui.getHeight()));
				if(backgroundImage==null)
				{
					try {
						backgroundImage=ImageIO.read(image);
					} catch (Exception e) {}
				}
				g.drawImage(backgroundImage, 0, 0, getWidth(),getHeight(),gui);
			}
		};
		return background;
	}
	
	public static JPanel getBackGroundPanel(final File image,final int width,final int height)
	{
		return new JPanel()
		{
			private static final long serialVersionUID = 1L;
			{
				setPreferredSize(new Dimension(width,height));
			}
			public void paintComponent(Graphics g)
			{
				if(getParent()!=null)
					if(getParent().getWidth()!=getWidth()||getParent().getHeight()!=getHeight())
						setPreferredSize(new Dimension(getParent().getWidth(),getParent().getHeight()));
				if(backgroundImage==null)
				{
					try {
						backgroundImage=ImageIO.read(image);
					} catch (Exception e) {}
				}
				g.drawImage(backgroundImage, 0, 0, getWidth(),getHeight(),gui);
			}
		};
	}
	
	/**
	 * Repacks the GUI and re locates it to center
	 */
	public static void repack() {
		gui.pack();
		setCenterToScreen(gui);
	}
	
	/**
	 * Sets the main frame of GUI
	 * @param frame The main GUI JFrame
	 */
	public static void setMainFrame(JFrame frame) {
		gui=frame;
		gui.addWindowStateListener(new WindowStateListener(){
			public void windowStateChanged(WindowEvent arg0) {
				if(background!=null)
					background.setPreferredSize(new Dimension(gui.getWidth(),gui.getHeight()));
				if(disabler!=null)
					disabler.setPreferredSize(new Dimension(gui.getWidth(),gui.getHeight()));
				if(transparent!=null)
					transparent.setPreferredSize(new Dimension(gui.getWidth(),gui.getHeight()));
			}
		});
	}
	
	/**
	 * Sets the icon to the Main frame of GUI
	 * @param iconFile file object of icon
	 */
	public static void setIcon(File iconFile){
		BufferedImage icon = null;
		try{
			icon=ImageIO.read(iconFile);
			gui.setIconImage(icon);
		}catch(Exception e){}
	}
}
